package com.androidmvc.base.utils;

import android.os.Environment;
import android.os.StatFs;

import com.androidmvc.base.constant.Constant;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileUtils {
    private static final String TAG = "FileUtils";
    private static String SDPATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + Constant.ROOT_PATH;

    public FileUtils() {
        // 得到当前外部存储设备的目录
        // /SDCARD
        SDPATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + Constant.ROOT_PATH;
    }

    /**
     * 判断外部存储卡是否可用
     *
     * @return
     */
    public static boolean isExternalStorageAvailable() {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            return true;
        }
        return false;
    }

    /**
     * 获取某文件夹大小
     *
     * @param file
     * @return
     */
    public static double getDirSize(File file) {
        //判断文件是否存在
        if (file.exists()) {
            //如果是目录则递归计算其内容的总大小
            if (file.isDirectory()) {
                File[] children = file.listFiles();
                double size = 0;
                for (File f : children)
                    size += getDirSize(f);
                return size;
            } else {//如果是文件则直接返回其大小,以“兆”为单位
                double size = (double) file.length() / 1024 / 1024;
                return size;
            }
        } else {
            L.i(TAG, "文件或者文件夹不存在，请检查路径是否正确！");
            return 0.0;
        }
    }

    /**
     * 获取储存文件夹根目录
     *
     * @return
     */
    public static File getDiskFile() {
        File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + Constant.ROOT_PATH);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }


    /**
     * 判断sd卡的状态
     *
     * @return
     */
    public static byte getSDCardStatus() {
        byte status;

        String sdState = Environment.getExternalStorageState();
        if (sdState.equals(Environment.MEDIA_MOUNTED)) {
            File sdcardDir = Environment.getExternalStorageDirectory();
            StatFs sf = new StatFs(sdcardDir.getPath());
            long availCount = sf.getAvailableBlocks();
            long blockSize = sf.getBlockSize();
            long availSize = availCount * blockSize / 1024;

            if (availSize >= 3072) {
                status = Constant.SD_CARD_AVAILABLE;
            } else {
                status = Constant.SD_CARD_SPACE_NOT_ENOUGH;
            }
        } else {
            status = Constant.SD_CARD_NOT_AVAILABLE;
        }

        return status;
    }

    /**
     * 获取达赏缓存储存文件夹根目录
     *
     * @return
     */
    public static File getDiskCacheFile() {
        File file = new File(getDiskFile() + "/" + Constant.ROOT_CACHE_PATH);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }

    public static boolean isCacheFile(String cacheName) {
        File file = new File(getDiskFile(), cacheName);
        int state = getSDCardStatus();
        boolean result = file.exists();
        if ((state == Constant.SD_CARD_AVAILABLE) && result) {
            return true;
        }
        return false;
    }

    public static String readDisckCach(String fileName) {
        File file = new File(getDiskFile(), fileName);
        try {
            FileInputStream in = new FileInputStream(file);
            int size = in.available();
            byte[] buffer = new byte[size];
            in.read(buffer);
            in.close();
            String str = new String(buffer, "utf-8");
            return str;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return "";
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    public static boolean writeDiskCache(byte[] data, String cacheName) {
        boolean result = false;
        int state = getSDCardStatus();
        if (state == Constant.SD_CARD_AVAILABLE) {
            try {
                File file = new File(getDiskFile(), cacheName);
                ByteArrayInputStream in = new ByteArrayInputStream(data);
                FileOutputStream out = new FileOutputStream(file);
                byte buffer[] = new byte[4 * 1024];
                int len = 0;
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                out.flush();
                out.close();
                in.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                result = false;
            } catch (IOException e) {
                e.printStackTrace();
                result = false;
            }
            return true;
        }

        return result;
    }


    public static String getSDPATH() {
        return SDPATH;
    }

    /**
     * 在SD卡上创建文件
     *
     * @throws IOException
     */
    public static File creatSDFile(String fileName) throws IOException {
        File file = new File(SDPATH + fileName);
        file.createNewFile();
        return file;
    }

    /**
     * 在SD卡上创建目录
     *
     * @param dirName
     */
    public static File creatSDDir(String dirName) {
        File dir = new File(SDPATH + dirName);
        dir.mkdirs();
        return dir;
    }

    /**
     * 判断SD卡上的文件夹是否存在
     */
    public static boolean isFileExist(String fileName) {
        File file = new File(SDPATH + fileName);
        return file.exists();
    }

    /**
     * 将一个InputStream里面的数据写入到SD卡中
     */
    public static File write2SDFromInput(String path, String fileName, InputStream input) {
        File file = null;
        OutputStream output = null;
        try {
            creatSDDir(path);
            file = creatSDFile(path + fileName);
            output = new FileOutputStream(file);
            byte buffer[] = new byte[4 * 1024];
            while ((input.read(buffer)) != -1) {
                output.write(buffer);
            }
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                output.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    /**
     * 复制文件
     *
     * @param sourcePath
     * @param targetPath
     * @throws IOException
     */
    public static void copyFile(String sourcePath, String targetPath) throws IOException {
        File oldFile = new File(sourcePath);
        File targetFile = new File(targetPath);
        if (!oldFile.exists())
            return;
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            inBuff = new BufferedInputStream(new FileInputStream(oldFile));
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inBuff.read(b)) != -1) {
                outBuff.write(b, 0, len);
            }
            outBuff.flush();
        } catch (Exception e) {

        } finally {
            if (inBuff != null)
                inBuff.close();
            if (outBuff != null)
                outBuff.close();
        }
    }

    /**
     * 创建新的图片文件
     *
     * @return
     */
    public static File getImgDirFile() {
        File file = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + Constant.ROOT_PATH
                    + Constant.IMG_PATH);
            if (!file.exists()) {
                file.mkdirs();
            }
        }

        return file;
    }

    /**
     * 将图片文件写入本地
     *
     * @param data
     * @param fileName
     * @return
     */
    public static File writeImageToFile(byte[] data, String fileName) {
        File file = null;
        if (data == null || data.length == 0) {
            return file;
        }
        try {
            file = new File(getImgDirFile(), fileName + Constant.IMG_SUFFIX);
            if (file != null) {
                FileOutputStream outStream = new FileOutputStream(file);
                outStream.write(data);
                outStream.flush();
                outStream.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    public static boolean saveFileToSDCard(byte[] data, String filename) {
        BufferedOutputStream bos = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File file = new File(SDPATH);
            if (!file.exists()) {
                boolean flags = file.mkdirs();
            }
            try {
                bos = new BufferedOutputStream(new FileOutputStream(new File(filename)));
                bos.write(data, 0, data.length);
                bos.flush();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    public static byte[] loadFileFromSDCard(String filepath) {
        BufferedInputStream bis = null;
        ByteArrayOutputStream baos = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File file = new File(filepath);
            if (file.exists()) {
                try {
                    baos = new ByteArrayOutputStream();
                    bis = new BufferedInputStream(new FileInputStream(file));
                    byte[] buffer = new byte[1024 * 8];
                    int c = 0;
                    while ((c = bis.read(buffer)) != -1) {
                        baos.write(buffer, 0, c);
                        baos.flush();
                    }
                    return baos.toByteArray();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (bis != null) {
                            bis.close();
                            baos.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return null;
    }

    /**
     * InputStream转byte数组
     *
     * @param input
     * @return
     * @throws IOException
     */
    public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }

    /**
     * 也可用作删除根目录，录音文件的目录
     *
     * @param filePath
     */
    public synchronized static boolean delFile(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 删除一个目录下所有文件
     *
     * @param filePath
     */
    public synchronized static void deleteAllFile(String filePath) {
        File dir = new File(filePath);
        if (dir == null || !dir.exists() || !dir.isDirectory())
            return;
        for (File file : dir.listFiles()) {
            if (file.isFile())
                file.delete();
        }
    }

    public synchronized static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                L.i(TAG, "删除单个文件" + fileName + "成功！");
                return true;
            } else {
                L.i(TAG, "删除单个文件" + fileName + "失败！");
                return false;
            }
        } else {
            L.i(TAG, "删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }
}
